package org.sample.pack;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/** 根据classList.properties 中的class Name 复制类文件 */
public class PackHelper {

    /** 目标文件夹 */
    private static final String TARGET = "G:/ClassFile/classes/";

    /** 类名列表 */
    private static final String SOURCE_PATH = "classList.properties";

    /** 是否保持目录结构 */
    private static final boolean STRUCTURE = true;

    public static void main(String[] args) throws IOException {
        ArrayList<String> classList = readConfig();

        for (String className : classList) {
            copyClass(className);
        }
    }

    /**
     * 拷贝类文件
     *
     * @param className 类名 如:java.lang.String
     * @throws IOException
     */
    @SuppressWarnings("rawtypes")
    private static void copyClass(String className) throws IOException {
        Class clazz = null;
        try {
            clazz = Class.forName(className);
        } catch (ClassNotFoundException e) {
            System.out.println("找不到类文件" + className);
            e.printStackTrace();
            return;
        }

        String targetDir = TARGET;
        if (STRUCTURE)
            targetDir = TARGET + clazz.getPackage().getName().replace(".", "/");

        new File(targetDir).mkdirs();

        String classSimpleName = clazz.getSimpleName();

        String classFileName = classSimpleName + ".class";

        File classFile = new File(clazz.getResource(classFileName).getPath());

        copyInternalClass(classSimpleName, classFile, targetDir);

        copy(classFile, targetDir + "/" + classFileName);

    }

    /**
     * 拷贝内部类
     *
     * @param simpleName 简单的类名 如：String
     * @param sourceFile 需要拷贝的类文件（根据该文件找到内部类）
     * @param targetDir  目标文件夹
     * @throws IOException
     */
    private static void copyInternalClass(String simpleName, File sourceFile, String targetDir) throws IOException {
        File parentDir = new File(sourceFile.getParent());

        File[] files = parentDir.listFiles();

        simpleName += "$";

        for (File file : files) {
            String name = file.getName();
            if (name.startsWith(simpleName))
                copy(file, targetDir + "/" + file.getName());
        }
    }

    /**
     * 拷贝文件
     *
     * @param sourceFile 源文件
     * @param targetPath 目标文件地址
     * @throws IOException
     */
    public static void copy(File sourceFile, String targetPath) throws IOException {
        System.out.println("Source\t" + sourceFile.getAbsolutePath());
        System.out.println("Target\t" + targetPath + "\n");

        FileInputStream fis = new FileInputStream(sourceFile);
        FileOutputStream fos = new FileOutputStream(targetPath);

        byte[] buffer = new byte[1024];
        int read = 0;

        while (-1 != (read = fis.read(buffer))) {
            fos.write(buffer, 0, read);
        }

        fos.close();
        fis.close();
    }

    /** 初始化 读取配置文件 */
    private static ArrayList<String> readConfig() throws IOException {
        new File(TARGET).mkdir();

        ArrayList<String> classList = new ArrayList<String>();

        String line = null;

        BufferedReader br = new BufferedReader(new FileReader(PackHelper.class.getResource(SOURCE_PATH).getPath()));

        while ((line = br.readLine()) != null) {
            classList.add(line);
        }

        br.close();
        return classList;
    }

}